import requests
from msal import ConfidentialClientApplication

class GraphClient:
    def __init__(self, tenant_id, client_id, client_secret):
        self.authority = f"https://login.microsoftonline.com/{tenant_id}"
        self.app = ConfidentialClientApplication(
            client_id=client_id,
            client_credential=client_secret,
            authority=self.authority
        )
        self._access_token = None
        
    def _get_token(self):
        """获取访问令牌"""
        result = self.app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"])
        return result["access_token"]
    
    def make_request(self, method, endpoint, params=None, data=None):
        """执行API请求"""
        headers = {
            "Authorization": f"Bearer {self._get_token()}",
            "Content-Type": "application/json"
        }
        url = f"https://graph.microsoft.com/v1.0/{endpoint}"
        
        for _ in range(3):  # 三级重试机制
            response = requests.request(method, url, headers=headers, params=params, json=data)
            if response.status_code == 429:  # 处理速率限制
                time.sleep(int(response.headers.get('Retry-After', 10)))
                continue
            response.raise_for_status()
            return response.json()
        raise ConnectionError("API请求失败")

    def paginate(self, endpoint, params=None):
        """处理分页结果"""
        while endpoint:
            data = self.make_request("GET", endpoint, params=params)
            yield from data.get("value", [])
            endpoint = data.get("@odata.nextLink", "").split("v1.0/")[-1]